/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.debugger.jpda; import java.beans.PropertyEditor; import java.util.ResourceBundle; import java.util.List; import java.util.LinkedList; import java.text.MessageFormat; import javax.swing.SwingUtilities; import javax.swing.JComponent; import com.sun.jdi.ReferenceType; import com.sun.jdi.ThreadReference; import com.sun.jdi.Location; import com.sun.jdi.Method; import com.sun.jdi.VMMismatchException; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.request.ExceptionRequest; import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.ClassPrepareRequest; import com.sun.jdi.request.EventRequest; import com.sun.jdi.event.ExceptionEvent; import com.sun.jdi.event.ClassPrepareEvent; import com.sun.jdi.event.Event; import com.sun.jdi.event.EventSet; import com.sun.jdi.event.EventIterator; import com.sun.jdi.event.StepEvent; import org.openide.TopManager; import org.openide.explorer.propertysheet.editors.ChoicePropertyEditor; import org.openide.filesystems.FileObject; import org.openide.text.Line; import org.openide.nodes.Node; import org.openide.nodes.PropertySupport; import org.openide.util.NbBundle; import org.openide.util.actions.SystemAction; import org.netbeans.modules.debugger.jpda.util.*; import org.netbeans.modules.debugger.support.*; import org.netbeans.modules.debugger.support.actions.AddBreakpointAction; /** * Implementation of breakpoint on exception. * * @author Jan Jancura */ public class ExceptionBreakpoint extends ClassBreakpointEvent implements Executor, StopEvent { // static ...................................................................................... /** Property name constant. */ public static final String PROP_CATCH_TYPE = "catchType"; // NOI18N /** Catch type property value constant. */ public static final int EXCEPTION_CATCHED = 1; /** Catch type property value constant. */ public static final int EXCEPTION_UNCATCHED = 2; // variables ...................................................................................... /** Thread which stops on this breakpoint. */ private transient ThreadReference thread; /** Stores all EventRequests produced by this Event. */ private Requestor requestor; private ReferenceType tryClass; private JPDAVariable exception; private int catchType = EXCEPTION_UNCATCHED; { className = ((AddBreakpointAction) SystemAction.get (AddBreakpointAction.class)).getCurrentIdentifier (); } // Event impl ...................................................................................... /** * Returns the new instance of Breakpoint.Event. */ public CoreBreakpoint.Event getNewInstance () { return new ExceptionBreakpoint (); } /** * Sets breakpoint with specified properties. */ public boolean set () { //S ystem.out.println("ExceptionBreakpoint.set TRY " + this + " in " + getDebugger () ); // NOI18N JPDADebugger debugger = (JPDADebugger) getDebugger (); if (debugger.virtualMachine == null) return false; if ((getClassName () == null) || (getClassName ().trim ().length () < 1)) return false; if (requestor == null) requestor = new Requestor (debugger.requestManager); try { requestor.removeRequests (); // For unloaded classes ClassPrepareRequest cpr = debugger.requestManager.createClassPrepareRequest (); //S ystem.out.println ("ExceptionBreakpoint.set CLASSES " + getClassName ()); // NOI18N cpr.addClassFilter (getClassName ()); cpr.setSuspendPolicy (ExceptionRequest.SUSPEND_ALL); debugger.operator.register (cpr, this); requestor.add (cpr); cpr.enable (); List l = debugger.virtualMachine.classesByName (getClassName ()); if (l.size () == 0) return false; int i, k = l.size (); for (i = 0; i < k; i++) set (((ReferenceType) l.get (i))); return true; } catch (VMDisconnectedException e) { } return false; } /** * Removes breakpoint. */ public void remove () { //S ystem.out.println ("ExceptionBreakpoint.remove " + this); // NOI18N if (requestor != null) requestor.removeRequests (); } /** * Returns specific properties of this event. */ public Node.Property[] getProperties () { final ResourceBundle bundle = NbBundle.getBundle (VariableBreakpoint.class); return new Node.Property[] { new PropertySupport.ReadWrite ( CoreBreakpoint.PROP_CLASS_NAME, String.class, bundle.getString ("PROP_Exception_class_name"), bundle.getString ("HINT_Exception_class_name") ) { public Object getValue () { return getClassName (); } public void setValue (Object val) throws IllegalArgumentException { try { setClassName (((String) val).trim ()); } catch (ClassCastException e) { throw new IllegalArgumentException (); } } }, new PropertySupport.ReadWrite ( PROP_CATCH_TYPE, Integer.TYPE, bundle.getString ("PROP_Exception_type_name"), bundle.getString ("HINT_Exception_type_name") ) { public Object getValue () throws IllegalArgumentException { return new Integer (getCatchType ()); } public void setValue (Object val) throws IllegalArgumentException { try { setCatchType (((Integer) val).intValue ()); } catch (ClassCastException e) { throw new IllegalArgumentException (); } } public PropertyEditor getPropertyEditor () { return new ChoicePropertyEditor ( new int[] { EXCEPTION_CATCHED, EXCEPTION_UNCATCHED, EXCEPTION_CATCHED | EXCEPTION_UNCATCHED }, new String[] { bundle.getString ("CTL_Exception_type_catched"), bundle.getString ("CTL_Exception_type_uncatched"), bundle.getString ("CTL_Exception_type_both") } ); } } }; } /** * Returns line of breakpoint. */ public Line[] getLines () { return null; } /** * Returns actions available specially for this version of event. */ public CoreBreakpoint.Action[] getBreakpointActions () { CoreBreakpoint.Action[] myActions = new CoreBreakpoint.Action[] { new StopAction (), new PrintAction (PrintAction.BREAKPOINT_EXCEPTION_TEXT), }; CoreBreakpoint.Action[] actions = new CoreBreakpoint.Action [super.getBreakpointActions ().length + myActions.length]; System.arraycopy (super.getBreakpointActions (), 0, actions, 0, super.getBreakpointActions ().length); System.arraycopy (myActions, 0, actions, super.getBreakpointActions ().length, myActions.length); return actions; } /** * Aditional ifno about debugger state when this event occures. * If event do not produce this type of info, null is returned. */ public AbstractThread getThread () { if (thread == null) return null; JPDADebugger debugger = (JPDADebugger) getDebugger (); return debugger.threadManager.getThread (thread); } /** * Aditional ifno about debugger state when this event occures. * If event do not produce this type of info, null is returned. */ public CallStackFrame[] getCallStack () { return getThread ().getCallStack (); } /** * Aditional ifno about debugger state when this event occures. * If event do not produce this type of info, null is returned. */ public AbstractVariable getVariable () { return exception; } /** * Returns name of type of this event. */ public String getTypeName () { return "Exception"; // NOI18N } /** * Returns display name of this event. */ public String getTypeDisplayName () { return NbBundle.getBundle (ExceptionBreakpoint.class).getString ("CTL_Exception_event_name_type_name"); } /** * Returns display name of this instance of event. It will be used * as the name of the breakpoint. */ public String getDisplayName () { if ((getCatchType () & EXCEPTION_CATCHED) != 0) if ((getCatchType () & EXCEPTION_UNCATCHED) != 0) return new MessageFormat ( NbBundle.getBundle (ExceptionBreakpoint.class).getString ("CTL_Exception_event_name") ).format (new Object[] {getClassName ()}); else return new MessageFormat ( NbBundle.getBundle (ExceptionBreakpoint.class).getString ("CTL_Exception_event_name_catched") ).format (new Object[] {getClassName ()}); else return new MessageFormat ( NbBundle.getBundle (ExceptionBreakpoint.class).getString ("CTL_Exception_event_name_uncatched") ).format (new Object[] {getClassName ()}); } /** * Returns name of icon. */ public String getIconBase () { return "/org/netbeans/modules/debugger/resources/breakpointOnException"; // NOI18N } /** * Returns customizer visual component. */ public JComponent getCustomizer () { return new ExceptionBreakpointPanel (this); } // interface Executor ..................................................................... /** * Executes exception hit event. */ public void exec (com.sun.jdi.event.Event event) { //S ystem.out.println ("ExceptionBreakpoint.exec! " + this + " : " + event); // NOI18N if (event instanceof ClassPrepareEvent) { tryClass = ((ClassPrepareEvent) event).referenceType (); boolean v = set (tryClass); if (v && !getBreakpoint ().isValid ()) setValid (true); ((JPDADebugger) getDebugger ()).operator.resume (); return; } thread = ((ExceptionEvent) event).thread (); exception = new JPDAVariable ( (JPDADebugger) getDebugger (), "Exception", // NOI18N ((ExceptionEvent) event).exception (), "" // NOI18N ); perform (); } // StopEvent impl ...................................................................................... /** * Performs stop action. */ public void stop (boolean stop) { ((JPDADebugger) getDebugger ()).stop (stop, getThread ()); } // other methods ...................................................................................... /** * Returns catchType property value. * * @return catchType property value. */ public int getCatchType () { return catchType; } /** * Sets catchType property value. * * @param new value of catchType property. */ public void setCatchType (int catchType) { if (catchType == this.catchType) return; if ( (catchType & (EXCEPTION_CATCHED | EXCEPTION_UNCATCHED)) == 0 ) throw new IllegalArgumentException (); int old = this.catchType; this.catchType = catchType; firePropertyChange (PROP_CATCH_TYPE, new Integer (old), new Integer (catchType)); } /** * Sets exception breakpoint for given class. */ public boolean set (ReferenceType rt) { JPDADebugger debugger = (JPDADebugger) getDebugger (); if (debugger.virtualMachine == null) return false; try { //S ystem.out.println ("ExceptionBreakpoint.set for class " + rt); // NOI18N ExceptionRequest er = debugger.requestManager.createExceptionRequest ( rt, (EXCEPTION_CATCHED & catchType) != 0, (EXCEPTION_UNCATCHED & catchType) != 0 ); er.setSuspendPolicy (ExceptionRequest.SUSPEND_ALL); debugger.operator.register (er, this); requestor.add (er); er.enable (); return true; } catch (VMDisconnectedException e) { } catch (VMMismatchException e) { } catch (Exception e) { //S ystem.out.println ("ExceptionBreakpoint.set class exc. " + e); // NOI18N //e.p rintStackTrace (); } return false; } public String toString () { return "JPDAExceptionBreakpoint " + getClassName (); // NOI18N } } /* * Log * 12 Gandalf-post-FCS1.10.4.0 3/28/00 Daniel Prusa * 11 Gandalf 1.10 1/14/00 Daniel Prusa NOI18N * 10 Gandalf 1.9 1/13/00 Daniel Prusa NOI18N * 9 Gandalf 1.8 1/4/00 Jan Jancura Use trim () on user * input. * 8 Gandalf 1.7 11/9/99 Jan Jancura printstacktrace commented * out * 7 Gandalf 1.6 11/8/99 Jan Jancura Somma classes renamed * 6 Gandalf 1.5 11/5/99 Jan Jancura Empty values support * 5 Gandalf 1.4 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 4 Gandalf 1.3 9/28/99 Jan Jancura * 3 Gandalf 1.2 9/15/99 Jan Jancura * 2 Gandalf 1.1 9/3/99 Jan Jancura * 1 Gandalf 1.0 9/2/99 Jan Jancura * $ */